package aop;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author 26029
 * @date 2025/4/15
 * @description
 */
public class LearnAnnotation {
    @MyAnnotation("hello方法有注解")
    public void hello() {
        System.out.println("Hello!");
    }

    public void normal() {
        System.out.println("普通方法");
    }

    @AutoSet
    public int a;

    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
        LearnAnnotation learnAnnotation = new LearnAnnotation();
        Class<?> clazz = learnAnnotation.getClass();

        for (Method method : clazz.getDeclaredMethods()) {
            // 只处理有 @MyAnnotation 的方法
            if (method.isAnnotationPresent(MyAnnotation.class)) {
                MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
                String info = annotation.value();

                // 输出前置逻辑
                System.out.println(">>> 前置操作: " + info);

                // 调用方法
                method.invoke(learnAnnotation);

                // 输出后置逻辑
                System.out.println("<<< 后置操作: " + info);
            }
        }

        for (Field field : clazz.getDeclaredFields()) {
            if (field.isAnnotationPresent(AutoSet.class)) {
                AutoSet autoSet = field.getAnnotation(AutoSet.class);
                field.set(learnAnnotation, autoSet.value());
            }
        }

        System.out.println(learnAnnotation);
    }

    @Override
    public String toString() {
        return "LearnAnnotation{" +
                "a=" + a +
                '}';
    }
}

@Retention(RetentionPolicy.RUNTIME)  // 运行时保留（才能用反射读取）
@Target(ElementType.METHOD)          // 这个注解只能用在方法上
@interface MyAnnotation {
    String value() default "默认值";
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface AutoSet {
    int value() default 110;
}